#ifndef _BASE64_H_
#define _BASE64_H_
namespace qb
{
	//===================================
	//    Base64 编码
	//===================================
	inline char Encode_GetChar(uint8_t num)
	{
		return "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
			"abcdefghijklmnopqrstuvwxyz"
			"0123456789"
			"+/="[num];
	}

	//编码
	inline size_t Base64_Encode(char *pDest, const char *pSrc, size_t srclen)
	{
		uint8_t input[3], output[4];
		size_t i, index_src = 0, index_dest = 0;
		for(i = 0; i < srclen; i += 3)
		{
			//char [0]
			input[0] = pSrc[index_src++];
			output[0] = (uint8_t)(input[0] >> 2);
			pDest[index_dest++] = Encode_GetChar(output[0]);

			//char [1]
			if(index_src < srclen)
			{
				input[1] = pSrc[index_src++];
				output[1] = (uint8_t)(((input[0] & 0x03) << 4) + (input[1] >> 4));
				pDest[index_dest++] = Encode_GetChar(output[1]);
			}
			else
			{
				output[1] = (uint8_t)((input[0] & 0x03) << 4);
				pDest[index_dest++] = Encode_GetChar(output[1]);
				pDest[index_dest++] = '=';
				pDest[index_dest++] = '=';
				break;
			}

			//char [2]
			if(index_src < srclen)
			{
				input[2] = pSrc[index_src++];
				output[2] = (uint8_t)(((input[1] & 0x0f) << 2) + (input[2] >> 6));
				pDest[index_dest++] = Encode_GetChar(output[2]);
			}
			else
			{
				output[2] = (uint8_t)((input[1] & 0x0f) << 2);
				pDest[index_dest++] = Encode_GetChar(output[2]);
				pDest[index_dest++] = '=';
				break;
			}

			//char [3]
			output[3] = (uint8_t)(input[2] & 0x3f);
			pDest[index_dest++] = Encode_GetChar(output[3]);
		}
		//null-terminator
		pDest[index_dest] = 0;
		return index_dest;
	}

}
#endif // _BASE64_H_
